fix: scope machine-only settings to application (#1032)#1034
Open
EhabY wants to merge 1 commit into
Open
Conversation
EhabY
added a commit
that referenced
this pull request
Jul 15, 2026
… settings - Flip coder.sshConfig and coder.proxyBypass from machine to application scope for the same reason as the other settings in this branch: both are read during pre-connection setup and are subject to the same VS Code local-configuration exclusion described in #1032/#1034. - Re-review ignoreSync per setting instead of blanket-applying it. Settings holding a local file path or an executed local command keep ignoreSync: true (coder.binaryDestination, coder.headerCommand, coder.tlsCertFile, coder.tlsKeyFile, coder.tlsCaFile, coder.tlsCertRefreshCommand, coder.proxyLogDirectory, coder.globalFlags, coder.sshConfig). Plain URLs/hostnames/flags with no local-path dependency now sync like other application-scoped settings (coder.binarySource, coder.tlsAltHost, coder.proxyBypass, coder.sshFlags). - Document the Settings Sync behavior in the README and CHANGELOG.
EhabY
added a commit
that referenced
this pull request
Jul 15, 2026
Once a window has a remote connection, VS Code stops reading machine-scoped values from the local settings.json at all, with or without Profiles (hasRemote is the trigger, not profile usage). Add a README warning pointing back to #1032/#1034 so no one reintroduces machine scope without addressing this first.
EhabY
added a commit
that referenced
this pull request
Jul 16, 2026
We reproduced the intermittent revert deterministically: in a remote window the local User settings.json is parsed without machine scope, so a machine-scoped value is kept only until the extension registers its schema, after which the next re-parse (edit, Settings Sync write, profile switch, or tasks.json load) drops it to the default with no remote-side fallback. Move the mechanism detail out of the changelog into the README note and PR #1034, and remove the earlier "could not reproduce" hedge. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
EhabY
added a commit
that referenced
this pull request
Jul 16, 2026
Reword the README Settings Sync note and machine-scope warning to read more clearly, and remove the trailing "See the README note and #1034" sentence from the changelog entry. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
EhabY
added a commit
that referenced
this pull request
Jul 16, 2026
We reproduced the intermittent revert deterministically: in a remote window the local User settings.json is parsed without machine scope, so a machine-scoped value is kept only until the extension registers its schema, after which the next re-parse (edit, Settings Sync write, profile switch, or tasks.json load) drops it to the default with no remote-side fallback. Move the mechanism detail out of the changelog into the README note and PR #1034, and remove the earlier "could not reproduce" hedge.
4cb6849 to
77f4b97
Compare
EhabY
added a commit
that referenced
this pull request
Jul 16, 2026
Reword the README Settings Sync note and machine-scope warning to read more clearly, and remove the trailing "See the README note and #1034" sentence from the changelog entry.
Change coder.binarySource, coder.binaryDestination, coder.headerCommand, coder.tlsCertFile, coder.tlsKeyFile, coder.tlsCaFile, coder.tlsAltHost, coder.tlsCertRefreshCommand, coder.proxyLogDirectory, coder.proxyBypass, coder.sshConfig, coder.sshFlags, and coder.globalFlags from machine to application scope (all keep ignoreSync, so Settings Sync is unchanged). application scope keeps the SEC-200 goal of blocking workspace/folder overrides while fixing #1032: in a remote window VS Code filters machine-scoped keys out of the local User settings.json, so such a value holds only until the extension registers its schema on activation. The next re-parse of settings.json (edit, Settings Sync write, profile switch, or tasks.json load) then drops it to the default, with no remote-side fallback. application scope is honored regardless of timing. Document the mechanism and reproduction in the README and PR #1034.
77f4b97 to
5734041
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Changes these settings from
"scope": "machine"to"scope": "application"(all keepignoreSync: true, so Settings Sync behavior is unchanged):coder.binarySourcecoder.binaryDestinationcoder.headerCommandcoder.tlsCertFilecoder.tlsKeyFilecoder.tlsCaFilecoder.tlsAltHostcoder.tlsCertRefreshCommandcoder.proxyLogDirectorycoder.proxyBypass(deprecated in favor ofhttp.noProxy)coder.sshConfigcoder.sshFlagscoder.globalFlagsOnly the local-vs-remote read scope changes; sync behavior stays exactly as before. (We considered opting a few non-path settings into sync now that they are
application-scoped, but held off: a download URL, a TLS hostname, ano_proxylist, or CLI flags can still be machine- or network-specific, and that is a separate decision from this fix.)Why
machinescope was introduced in #965 (SEC-200) to stop workspace and foldersettings.jsonfrom overriding these settings.applicationscope preserves that goal: it can only be set in User settings, never overridden by workspace or folder settings.But
machinescope also makes VS Code stop honoring the User-configured value in a remote window. Reporters in #1032 saw the first connection work and later connections fail with no settings change; two independent users confirmed anapplication-scope build fixes it on Windows 11 and pinned the regression to v1.14.6, the release that shipped #965. All these settings are read at the same pre-connection point (right before SSH connects), so they share the exposure. Array settings (sshFlags/globalFlags) behave like the string ones, since scope resolution is per-key regardless of value type.The VS Code mechanism
In a remote window,
WorkspaceServicefilters the local user configuration throughLOCAL_MACHINE_SCOPES = [APPLICATION, WINDOW, RESOURCE, LANGUAGE_OVERRIDABLE](getLocalUserConfigurationScopesinconfigurationService.ts), which excludesMACHINE(seeconfiguration.ts). Amachine-scoped value can then only come from the remote machine's settings file, not the local one where the user set it. This is deliberate, long-standing design:http.proxyand fixed it the same way we do here: "Made proxy settings application scope by default. Once connected to remote, scope is changed accordingly."configurationService.test.ts>machine settings in local user settings does not override defaults: writes amachine-scoped key to the local usersettings.json, constructsWorkspaceServicewith aremoteAuthority, and assertsgetValue()returns the default.Reproduction (the "sometimes")
That unit test drops the value on a single connect because the schema is already registered when
WorkspaceServiceis built. At runtime the extension registers its schema during activation, after the window's first parse, so the outcome is timing-dependent. The deciding logic isshouldInclude(configurationModels.ts): an unregistered key (scopeundefined) is kept, while amachine-registered key is dropped underLOCAL_MACHINE_SCOPES.settings.jsonbefore the extension activates, so the key is unregistered and kept.onResolveRemoteAuthority) and registers itsmachine-scoped schema.settings.json(an edit, a Settings Sync write, a profile switch, or atasks.jsonload) re-applies the filter, now seesMACHINE, and drops the key to its default. There is no remote fallback.Reproduced with a source build of VS Code and a minimal UI extension (
scopetest.machineSetting,scope: machine) on an SSH remote, with local settings"scopetest.machineSetting": "value-from-USER-settings"and no remote fallback. Editingsettings.jsonafter activation flips the resolved value:getValue('scopetest.machineSetting')"value-from-USER-settings"MACHINE (2)""(default)shouldIncludelogged the deciding step at each parse (scopesisLOCAL_MACHINE_SCOPES=[1,4,5,6], noMACHINE):APPLICATION(1) is inLOCAL_MACHINE_SCOPES, so anapplication-scoped key is honored regardless of timing. That is the fix.This PR and investigation were assisted by Coder Agents on behalf of @EhabY.